//Plinio Santana de Brito
//NUSP 7696243
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

const double g0 = 9.80665;       // Gravidade inicial (nível do mar)
const double R = 6335437;       // Raio da Terra
const double rho0 = 1.2922;    // Densidade inicial do ar (nível do mar)
const double h = 0.0001;      // Passo de integracao para o método Runge-Kutta

double m0, mp, tq, Fp, alpha, Cd, r, Sf;
double V, F, m, D, g, S, H, gama, final;
int NUM_THREADS, find;
char ch;
pthread_t th[500];

double Forca(double tempo){
    if(tempo > tq)
        return 0;
    else
        return Fp;
}

double massa(double tempo){
    if(tempo > tq)
        return m0-mp;
    else
        return m0-mp*(tempo/tq);
}

double arrasto(double fV, double rho){
    return 0.5 * Cd * (M_PI*r*r) * rho * (fV*fV);
}

double rho(double H){
    return rho0*exp(-0.000101741*H);
}

double gravidade(double H){
    return (R*R*g0)/((R+H)*(R+H));
}

double f_EDO(double ft, double fV, double fgama, double fS, double fH){
    return ((Forca(ft)*cos(alpha))/massa(ft))-(arrasto(fV,rho(fH))/massa(ft))-(gravidade(fH)*sin(fgama));
}

double g_EDO(double gt, double gV, double ggama, double gS, double gH){
    return ((Forca(gt)*sin(alpha))/(massa(gt)*gV))-(gravidade(gH)*(cos(ggama)/gV));
}

double h_EDO(double ht, double hV, double hgama, double hS, double hH){
    return hV*cos(hgama);
}

double i_EDO(double it, double iV, double igama, double iS, double iH){
    return iV*sin(igama);
}

double erro(double Sf, double S){
    return fabs(Sf-S)/fabs(Sf);
}

double rad(double grau){
    return (grau*M_PI)/180;
}


void threads(void *param){
    int i, over = 0;
    int j;
    double K1, K2, K3, K4; //Termos usados para a EDO
    double L1, L2, L3, L4; //Termos usados para a EDO
    double M1, M2, M3, M4; //Termos usados para a EDO
    double N1, N2, N3, N4; //Termos usados para a EDO

    int N = *(int*)param;
    
    double t,y,z,w,a;
    
    double angulo, i_angulo, f_angulo;
    
    i_angulo = (N*((180-gama)/NUM_THREADS))+gama;
    f_angulo = ((N+1)*((180-gama)/NUM_THREADS))+gama;

    angulo = i_angulo;

    do{
        if(find == 1){
            printf("FUI!\n");
            break;
        }

        t = 0;          //Tempo
        y = V;          //Velocidade
        z = rad(angulo);//Angulo de lançamento
        w = S;          //Distancia horizontal
        a = H;          //Altura

        for(j=0;a >= 0;j++){
            K1 = f_EDO(t, y, z, w, a);
            L1 = g_EDO(t, y, z, w, a);
            M1 = h_EDO(t, y, z, w, a);
            N1 = i_EDO(t, y, z, w, a);

            K2 = f_EDO(t+(h/2), y+((h/2)*K1), z+((h/2)*L1), w+((h/2)*M1), a+((h/2)*N1));
            L2 = g_EDO(t+(h/2), y+((h/2)*K1), z+((h/2)*L1), w+((h/2)*M1), a+((h/2)*N1));
            M2 = h_EDO(t+(h/2), y+((h/2)*K1), z+((h/2)*L1), w+((h/2)*M1), a+((h/2)*N1));
            N2 = i_EDO(t+(h/2), y+((h/2)*K1), z+((h/2)*L1), w+((h/2)*M1), a+((h/2)*N1));

            K3 = f_EDO(t+(h/2), y+((h/2)*K2), z+((h/2)*L2), w+((h/2)*M2), a+((h/2)*N2));
            L3 = g_EDO(t+(h/2), y+((h/2)*K2), z+((h/2)*L2), w+((h/2)*M2), a+((h/2)*N2));
            M3 = h_EDO(t+(h/2), y+((h/2)*K2), z+((h/2)*L2), w+((h/2)*M2), a+((h/2)*N2));
            N3 = i_EDO(t+(h/2), y+((h/2)*K2), z+((h/2)*L2), w+((h/2)*M2), a+((h/2)*N2));

            K4 = f_EDO(t+h, y + (h*K3), z + (h*L3), w + (h*M3), a+(h*N3));
            L4 = g_EDO(t+h, y + (h*K3), z + (h*L3), w + (h*M3), a+(h*N3));
            M4 = h_EDO(t+h, y + (h*K3), z + (h*L3), w + (h*M3), a+(h*N3));
            N4 = i_EDO(t+h, y + (h*K3), z + (h*L3), w + (h*M3), a+(h*N3));

            t += h;
            y += (h*(K1+(2*K2)+(2*K3)+K4))/6;
            z += (h*(L1+(2*L2)+(2*L3)+L4))/6;
            w += (h*(M1+(2*M2)+(2*M3)+M4))/6;
            a += (h*(N1+(2*N2)+(2*N3)+N4))/6;
        }

        angulo += 0.1;
        
        if(ch == 'R'){
            if(angulo > f_angulo){
                r += 0.005;
                angulo = i_angulo;
            }
        }

        if(angulo >= f_angulo){
            over = 1;
        }
    
    }while((erro(Sf,w) > 0.01) && (angulo < f_angulo));
    
    if(over == 0){
        printf("%c %lf %lf\n", ch, rad(angulo-0.1), r);
        find = 1;
        for (i = 0; i < NUM_THREADS; i++){
            if((i != N)){
                pthread_kill(th[i], 1);
            }
        }
    }
}


int main(int argc, char *argv[]) {

    int i;
    NUM_THREADS = 3;
    int num_th[NUM_THREADS];
    find =0;

    V = 0.1;        //Velocidade Inicial
    H = 0;          //Altura Inicial
    S = 0;          //Deslocamento horizontal inicial
    gama = 0;       //Angluo de lançamento

    scanf("%c",&ch);

    if(ch == 'G'){
        scanf("%lf",&m0);
        scanf("%lf",&mp);
        scanf("%lf",&tq);
        scanf("%lf",&Fp);
        scanf("%lf",&alpha);
        scanf("%lf",&Cd);
        scanf("%lf",&r);
        scanf("%lf",&Sf);
    }
    else if(ch == 'R'){
        scanf("%lf",&m0);
        scanf("%lf",&mp);
        scanf("%lf",&tq);
        scanf("%lf",&Fp);
        scanf("%lf",&alpha);
        scanf("%lf",&Cd);
        scanf("%lf",&Sf);
        r = 0.005;
    }
    else{
        printf("Entrada nao reconhecida\n");
        return -1;
    }


    for (i = 0; i < NUM_THREADS ; i++){
        num_th[i]=i;
        pthread_create(&th[num_th[i]], NULL, threads, (void *)&num_th[i]);
    }

    for (i = 0; i< NUM_THREADS ; i++){ 
        pthread_join (th[num_th[i]], NULL);
    }

    return 0;
}